package com.hitqz.robot.driver.netty.protocol.decoder;

import com.hitqz.robot.driver.dto.robot.MessageRobotDto;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 机器人控制信息的解码器
 * @author xupkun
 * @date 2023/8/4
 */
@Slf4j
public class RobotControllerDecoder extends ByteToMessageDecoder {

    private MessageRobotDto lastRobotDto;

    private static final int INNER_DATA_LENGTH = 6;
    private static final AtomicInteger readMaxTimes = new AtomicInteger(0);



    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
        try {
            byteBuf.markReaderIndex();
            int head = byteBuf.readByte();
            if (head != 0x5A) {
                byteBuf.resetReaderIndex();
                return;
            }
            int version = byteBuf.readByte();
            if (version != 1) {
                log.info("版本号错误: 版本号={}", version);
                int currentReadMaxTimes = readMaxTimes.incrementAndGet();
                byteBuf.resetReaderIndex();
                if (currentReadMaxTimes > 20) {
                    channelHandlerContext.channel().close();
                }
                return;
            }
            readMaxTimes.set(0);
            short sn = byteBuf.readShort();
            if (byteBuf.readableBytes() < (INNER_DATA_LENGTH + 4)) {
                log.info("可以读取的长度数量比较少，回滚数据");
                byteBuf.resetReaderIndex();
                return ;
            }
            int dataLength = byteBuf.readInt();
            if ((dataLength )< 0 || (dataLength + INNER_DATA_LENGTH)> byteBuf.readableBytes()) {
                byteBuf.resetReaderIndex();
                return;
            }

            short cmd = byteBuf.readShort();
            ByteBuf innerDataBuf = byteBuf.readSlice(INNER_DATA_LENGTH);
            ByteBuf dataBuf = byteBuf.readSlice(dataLength);
            lastRobotDto = new MessageRobotDto(sn, cmd, dataBuf.toString(StandardCharsets.UTF_8));
            list.add(lastRobotDto);
        } catch (Exception e) {
            log.error("解码过程中发生异常: {}", e.getMessage(), e);
            byteBuf.resetReaderIndex();
            throw e;
        }
    }
}
